#include "common.h"

void init_exti_pin(void)
{
    GPIO_InitTypeDef gpio_init;
    gpio_init.Mode  = GPIO_MODE_IT_RISING;
    gpio_init.Pin   = GPIO_PIN_2;
    gpio_init.Pull  = GPIO_PULLDOWN;
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOC, &gpio_init);
}

void init_extiLine2(void)  // 刹车信号中断输入初始化
{
    init_exti_pin();

    RCC->APB2ENR |= (1 << 0);
    AFIO->EXTICR[0] = (2 << 8);
    EXTI->RTSR |= (1 << 2);

    EXTI->PR = (1 << 2);
    EXTI->IMR |= (1 << 2);

    HAL_NVIC_SetPriority(EXTI2_IRQn, 0, 0);
    NVIC_EnableIRQ(EXTI2_IRQn);
}
// 外部中断配置函数
// 只针对GPIOA~G;不包括PVD,RTC和USB唤醒这三个
// 参数:GPIOx:0~6,代表GPIOA~G;BITx:需要使能的位;TRIM:触发模式,1,下升沿;2,上降沿;3，任意电平触发
// 该函数一次只能配置1个IO口,多个IO口,需多次调用
// 该函数会自动开启对应中断,以及屏蔽线
// 待测试...
// Ex_NVIC_Config专用定义
#define GPIO_A 0
#define GPIO_B 1
#define GPIO_C 2
#define GPIO_D 3
#define GPIO_E 4
#define GPIO_F 5
#define GPIO_G 6
#define FTIR   1  // 下降沿触发
#define RTIR   2  // 上升沿触发
void Ex_NVIC_Config(uint8_t GPIOx, uint8_t BITx, uint8_t TRIM)
{
    uint8_t EXTADDR;
    uint8_t EXTOFFSET;
    EXTADDR   = BITx / 4;  // 得到中断寄存器组的编号
    EXTOFFSET = (BITx % 4) * 4;
    RCC->APB2ENR |= 0x01;  // 使能io复用时钟

    AFIO->EXTICR[EXTADDR] &= ~(0x000F << EXTOFFSET);  // 清除原来设置！！！
    AFIO->EXTICR[EXTADDR] |= GPIOx << EXTOFFSET;      // EXTI.BITx映射到GPIOx.BITx

    // 自动设置
    EXTI->IMR |= 1 << BITx;  //  开启line BITx上的中断
                             // EXTI->EMR|=1<<BITx;//不屏蔽line BITx上的事件 (如果不屏蔽这句,在硬件上是可以的,但是在软件仿真的时候无法进入中断!)
    if (TRIM & 0x01)
        EXTI->FTSR |= 1 << BITx;  // line BITx上事件下降沿触发
    if (TRIM & 0x02)
        EXTI->RTSR |= 1 << BITx;  // line BITx上事件上升降沿触发
}

// PC12
void init_exti_PC12(void)
{
    GPIO_InitTypeDef gpio_init;
    gpio_init.Mode  = GPIO_MODE_IT_RISING;
    gpio_init.Pin   = GPIO_PIN_12;
    gpio_init.Pull  = GPIO_PULLDOWN;
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOC, &gpio_init);
}
void init_extiLine12(void)  // 刹车信号中断输入初始化
{
    init_exti_PC12();

    // RCC->APB2ENR |= (1 << 0);
    // AFIO->EXTICR[0] = (12 << 8);
    // EXTI->RTSR |= (1 << 12);
    Ex_NVIC_Config(GPIO_C, 12, FTIR);  // 上升沿触发
    // Ex_NVIC_Config(GPIO_A, 13, FTIR); // 下降沿触发
    EXTI->PR = (1 << 12);  // 清除LINE15上的中断标志位
    // EXTI->IMR |= (1 << 12);

    HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
    NVIC_EnableIRQ(EXTI15_10_IRQn);
}

void EXTI2_IRQHandler(void)
{
    if (1 == adaptor_parm.part.laser_module_adaptor_parm.check_feature_1.part.brake) {
        brake_interrupt_cnt++;
        Delay_1ms(1);
        if (HAL_GPIO_ReadPin(Break_In_GPIO, Break_In_Pin) == ON) {
            brake_state = 1;
            Laser_Health_Refresh();
            EXTI->IMR &= ~(1 << 2);  // 屏蔽line2上的中断
            EXTI->PR = (1 << 2);
        }
    }

    EXTI->PR = (1 << 2);
}

// 外部中断15~10服务程序
void EXTI15_10_IRQHandler(void)
{
    Delay_1ms(1);
    if (HAL_GPIO_ReadPin(Water_Press_GPIO, Water_Press_Pin) == OFF) {
        brake_state                                                = 1;
        operate_parm.laser_operate_data.fault_code2.bit.seedSrcErr = 1;
        Laser_Health_Refresh();

        EXTI->PR = (1 << 12);  // 清除LINE12上的中断标志位
    }
    EXTI->PR = (1 << 12);
}
